﻿/*
 * TODO:
 * Add Aircraft Collision Detection CheckForCollisions()
 * Add Enter/Exit AI into ComeIntoAirspace()
 * Remove Aircraft Once Landed
 * Move based on ATC Commands so add API for commands to be put into aicraft manager
 *  then update UI
 * Alot of other Shit to be added
*/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ATCSim.Objects;
using System.Threading;
using System.Media;
namespace ATCSim.Objects
{
    class AircraftManager
    {
        System.Windows.Forms.Timer _timer;
        private Random rand = new Random(DateTime.Now.Millisecond);
        private List<Aircraft> _AircraftList = new List<Aircraft>();
        HoldingZones _HoldingZones;
        Airport _Airport;
        SoundPlayer sp;

        public AircraftManager(ListBox TakeOffListBox)
        {
            _HoldingZones = new HoldingZones(this);
            _Airport = new Airport(this, TakeOffListBox);
            sp = new SoundPlayer("c123.wav");
        }
        public List<Aircraft> AircraftList
        {
            get
            {
                return _AircraftList;
            }
        }
        public Airport Airport
        {
            get
            {
                return _Airport;
            }
        }
#region Private Methods
        //Calls every Airplanes Move() inside _AircraftList to move planes
        private void MoveAircraft()
        {
            for (int i = 0; i < _AircraftList.Count; i++)
            {
                _AircraftList.ElementAt(i).Update();
                //_AircraftList.ElementAt(i).MoveTo(100,700);
            }
        }
        //Spawns Aircraft randomly between rand.Next(15, 45)
        private void CheckCollision()
        {
            #region CheckIfAircraftLeftScreenThenRemove
            for (int i = 0; i < _AircraftList.Count; i++)
            {
                try
                {
                    if (_AircraftList.ElementAt(i).Position.X <= 200 || _AircraftList.ElementAt(i).Position.X + 15 >= 1033 || _AircraftList.ElementAt(i).Position.Y + 15 <= 0 || _AircraftList.ElementAt(i).Position.Y >= 737)
                    {
                        _AircraftList.RemoveAt(i);
                    }
                }
                catch (Exception e)
                {
                    MessageBox.Show(e.ToString());
                }
            }
            #endregion
            #region CheckIfAirplaneLanded
            for (int i = 0; i < _AircraftList.Count; i++)
            {
                try
                {
                    if ((_AircraftList.ElementAt(i).Position.X >= 590 && _AircraftList.ElementAt(i).Position.X + 15 <= 630) &&
                        (_AircraftList.ElementAt(i).Position.Y + 15 >= 340 && _AircraftList.ElementAt(i).Position.Y <= 345) &&
                        (_AircraftList.ElementAt(i).Altitude <= 1500 && _AircraftList.ElementAt(i).Altitude != 1001) &&
                        (_AircraftList.ElementAt(i).Speed <= 165) &&
                        ((_AircraftList.ElementAt(i).Heading >= 350 && _AircraftList.ElementAt(i).Heading <= 360) ||
                        (_AircraftList.ElementAt(i).Heading >= 0 && _AircraftList.ElementAt(i).Heading <= 10) ||
                        (_AircraftList.ElementAt(i).Heading >= 170 && _AircraftList.ElementAt(i).Heading <= 190))
                        )
                    {
                        _AircraftList.RemoveAt(i);
                    }
                }
                catch (Exception e)
                {
                    MessageBox.Show(e.ToString());
                }
            }
            #endregion
            foreach (Aircraft Aircraft1 in _AircraftList)
            {
                #region RemoveCollisionWhenOutSidebound
                if (Aircraft1.CollidedWith != null)
                {
                    if (!((Aircraft1.Position.X + 15 >= Aircraft1.CollidedWith.Position.X && Aircraft1.Position.X <= Aircraft1.CollidedWith.Position.X ||
                        Aircraft1.CollidedWith.Position.X + 15 >= Aircraft1.Position.X && Aircraft1.CollidedWith.Position.X <= Aircraft1.Position.X)
                        &&
                        (Aircraft1.Position.Y + 15 >= Aircraft1.CollidedWith.Position.Y && Aircraft1.Position.Y <= Aircraft1.CollidedWith.Position.Y ||
                        Aircraft1.CollidedWith.Position.Y + 15 >= Aircraft1.Position.Y && Aircraft1.CollidedWith.Position.Y <= Aircraft1.Position.Y)))
                    {
                        Aircraft1.AircraftColor = Brushes.Black;
                        Aircraft1.CollidedWith.AircraftColor = Brushes.Black;
                        //Aircraft1.Collision = false;
                        //Aircraft1.CollidedWith.Collision = false;
                        Aircraft1.CollidedWith.CollidedWith = null;
                        Aircraft1.CollidedWith = null;
                    }
                }
                #endregion
                #region CheckForCollisionSetSoTurnRed
                foreach (Aircraft Aircraft2 in _AircraftList)
                {
                    #region CheckForCollisionTurnRed
                    if ((Aircraft1.Position.X + 15 >= Aircraft2.Position.X && Aircraft1.Position.X <= Aircraft2.Position.X ||
                        Aircraft2.Position.X + 15 >= Aircraft1.Position.X && Aircraft2.Position.X <= Aircraft1.Position.X)
                        &&
                        (Aircraft1.Position.Y + 15 >= Aircraft2.Position.Y && Aircraft1.Position.Y <= Aircraft2.Position.Y ||
                        Aircraft2.Position.Y + 15 >= Aircraft1.Position.Y && Aircraft2.Position.Y <= Aircraft1.Position.Y) &&
                        (Aircraft1.Altitude+1000 >= Aircraft2.Altitude && Aircraft1.Altitude-1000 <= Aircraft2.Altitude))
                    {
                        if (Aircraft1.ID.CompareTo(Aircraft2.ID) != 0)
                        {
                            if (Aircraft1.CollidedWith == null && Aircraft2.CollidedWith == null)
                            {
                                Aircraft1.AircraftColor = Brushes.Red;
                                Aircraft2.AircraftColor = Brushes.Red;
                                //Aircraft1.Collision = true;
                                //Aircraft2.Collision = true;
                                Aircraft1.CollidedWith = Aircraft2;
                                Aircraft2.CollidedWith = Aircraft1;

                                System.Media.SystemSounds.Exclamation.Play();
                                sp.Play();
                            }
                        }
                    }
                    #endregion
                    //Need to work on this still
                    #region CheckIfAircraftActuallyHit
                    if ((Aircraft1.Position.X + 1 >= Aircraft2.Position.X && Aircraft1.Position.X <= Aircraft2.Position.X ||
                        Aircraft2.Position.X + 1 >= Aircraft1.Position.X && Aircraft2.Position.X <= Aircraft1.Position.X)
                        &&
                        (Aircraft1.Position.Y + 1 >= Aircraft2.Position.Y && Aircraft1.Position.Y <= Aircraft2.Position.Y ||
                        Aircraft2.Position.Y + 1 >= Aircraft1.Position.Y && Aircraft2.Position.Y <= Aircraft1.Position.Y) &&
                        (Aircraft1.Altitude + 1000 >= Aircraft2.Altitude && Aircraft1.Altitude - 1000 <= Aircraft2.Altitude)&&
                        Aircraft1.ID.CompareTo(Aircraft2.ID) != 0)
                    {
                        _AircraftList.Remove(Aircraft1);
                        _AircraftList.Remove(Aircraft2);
                        MessageBox.Show("A Collision Has Occured", "Collision");
                        return;
                    }
                    #endregion
                }
                #endregion
            }
        }
#endregion
        public bool SpawnAircraft()
        {
            String[] idPickList = { "NW", "AA", "DA", "ME", "AW", "UA", "SW", "CA", "PA", "PK", "PD", "RK", "RD" };
            String airlineIDNum = idPickList[rand.Next(0, 12)];
            airlineIDNum += rand.Next(100, 999);
            while (AircraftIDExsists(airlineIDNum) && _Airport.AircraftIDExsists(airlineIDNum))
            {
                airlineIDNum = idPickList[rand.Next(0, 12)];
                airlineIDNum += rand.Next(1, 999);
            }
            return _HoldingZones.Add(airlineIDNum);
        }

        //Calls every Airplanes DrawAirplane() inside _AircraftList to draw planes
        public void DrawAllAircraft(System.Windows.Forms.PaintEventArgs e)
        {
            for (int i = 0; i < _AircraftList.Count; i++)
            {
                _AircraftList.ElementAt(i).DrawAirplane(e);
            }
        }

        //Is called from main form to move and do any aircraft processing
        public void UpdateAllAircraft(System.Windows.Forms.Timer timer)
        {
            _timer = timer;
            CheckCollision();
            MoveAircraft();
            _HoldingZones.MoveAircraftInHoldingZoneUpdate();
            _HoldingZones.FlyIntoAirspaceUpdate();
            _Airport.FlyOutOfAirspaceUpdate();
        }
        public bool AircraftIDExsists(String ID) 
        {
            for (int i = 0; i < _AircraftList.Count; i++)
            {
                if (_AircraftList.ElementAt(i).ID.CompareTo(ID.ToUpper()) == 0)
                    return true;
            }
            return false;
        }
        public Aircraft FindAircraft(String ID)
        {
            for (int i = 0; i < _AircraftList.Count; i++)
            {
                if (_AircraftList.ElementAt(i).ID.CompareTo(ID.ToUpper()) == 0)
                    return _AircraftList.ElementAt(i);
            }
            return null;
        }
        public Aircraft IsXYWithinAircraft(float x, float y)
        {
            foreach (Aircraft Aircraft in _AircraftList)
            {
                if ((x <= Aircraft.Position.X+15) &&
                    (x >= Aircraft.Position.X) &&
                    (y <= Aircraft.Position.Y+15)&&
                    (y >= Aircraft.Position.Y))
                {
                    return Aircraft;
                }
            }
            return null;
        }
 #region API For ATC Commands
        public void GoToAltitude(String ID, int Altitude)
        {
            Aircraft tmpAircraft = FindAircraft(ID);
            if(tmpAircraft != null)
                tmpAircraft.ToAltitude = Altitude;

        }
        public void TurnToHeading(String ID, int Heading, bool Left)
        {
            //.6 Degress per 3 seconds for standard C-172 (360Deg in 2 Min)
            Aircraft tmpAircraft = FindAircraft(ID);
            if (tmpAircraft != null)
            {
                tmpAircraft.ToHeading = Heading;
                tmpAircraft.TurnLeft = Left;
            }

        }
        public void GoToSpeed(String ID, int speed)
        {
            //.6 Degress per 3 seconds for standard C-172 (360Deg in 2 Min)
            Aircraft tmpAircraft = FindAircraft(ID);
            if (tmpAircraft != null)
            {
                tmpAircraft.ToSpeed = speed;
            }

        }
        public void ComeIntoAirspace(Aircraft SelectedAircraft)
        {
            _HoldingZones.MoveAircraftIntoAirspace(SelectedAircraft);
        }
#endregion
    }
}
